package com.neusoft.bizcore.webauth.secret.ding;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import com.neusoft.bizcore.auth.common.bean.UserBean;
import com.neusoft.bizcore.web.dto.result.ResultDTO;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.bizcore.webauth.secret.BizcoreAuthenticationException;
import com.neusoft.bizcore.webauth.secret.WebAuthMicroService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class DingAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private WebAuthMicroService webAuthMicroService;

    @Override
    public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
        final DingAuthenticationToken preAuthentication = (DingAuthenticationToken) authentication;
        final String authcode = preAuthentication.getAuthCode();
        final String username = (String) preAuthentication.getPrincipal();
        final String password = (String) preAuthentication.getCredentials();

        if (StringUtils.isEmpty(authcode)) {
            DingAuthenticationProvider.log.error("参数错误");
            throw new BizcoreAuthenticationException("参数错误", username);
        }
        ResultDTO<UserBean> result;

        final Map<String, String> params = new HashMap<>();
        params.put("authCode", authcode);
        params.put("username", username);
        params.put("password", password);
        try {
            result = this.webAuthMicroService.loginByDingUser(params);
        } catch (final UnitedException e) {
            throw new BizcoreAuthenticationException(e.getMessage(), username);
        }

        final UserBean userBean = result.getData();

        if (!userBean.isEnabled()) {
            DingAuthenticationProvider.log.warn("用户[" + userBean.getUsername() + "]已被禁用");
            throw new BizcoreAuthenticationException("用户已被禁用", username);
        }
        final Collection<? extends GrantedAuthority> authorities = userBean.getRoles().stream()
                .map(role -> new SimpleGrantedAuthority(role.getRole())).collect(Collectors.toSet());

        final DingAuthenticationToken token = new DingAuthenticationToken(
                userBean, authentication.getCredentials(),
                authorities);
        token.setDetails(authentication.getDetails());

        return token;
    }

    @Override
    public boolean supports(final Class<?> authentication) {
        return (DingAuthenticationToken.class
                .isAssignableFrom(authentication));
    }

}
